package com.lanchetech.user.service.impl;


import com.alibaba.excel.util.CollectionUtils;
import com.alibaba.fastjson.JSON;
import com.baidu.fsg.uid.UidGenerator;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.lanchetech.bean.dto.SnapshotDTO;
import com.lanchetech.bean.request.*;
import com.lanchetech.bean.response.*;
import com.lanchetech.bean.util.PageHelpUtil;
import com.lanchetech.bean.vo.*;
import com.lanchetech.common.enums.*;
import com.lanchetech.dao.*;
import com.lanchetech.entity.*;
import com.lanchetech.service.*;
import com.lanchetech.user.service.MerchantService;
import com.lanchetech.user.service.OrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class MerchantServiceImpl implements MerchantService {
    private final Logger log = LoggerFactory.getLogger(this.getClass());
    @Autowired
    AfterSaleMapper afterSaleMapper;

    @Autowired
    SkuMapper skuMapper;

    @Resource
    UidGenerator uidGenerator;

    @Autowired
    WxPayService wxPayService;

    @Autowired
    OrdersMapper ordersMapper;

    @Autowired
    OrderSkuMapper orderSkuMapper;

    @Autowired
    TenantWithdrawMapper tenantWithdrawMapper;

    @Autowired
    TenantMapper tenantMapper;

    @Autowired
    TenantFlowMapper tenantFlowMapper;

    @Autowired
    SpuMapper spuMapper;

    @Autowired
    OrderAddressMapper orderAddressMapper;

    @Autowired
    ShopMapper shopMapper;

    @Value("${domain.url}")
    private String domainUrl;

    @Autowired
    BossMapper bossMapper;

    @Autowired
    ShopStatisticsMapper shopStatisticsMapper;

    @Autowired
    LogisticsService logisticsService;

    @Autowired
    OrderPayMapper orderPayMapper;

    @Autowired
    CardFlowMapper cardFlowMapper;

    @Autowired
    UserMapper userMapper;

    @Autowired
    UserCommissionMapper userCommissionMapper;

    @Autowired
    ConsumptionService consumptionService;

    @Autowired
    RewardQueueMapper rewardQueueMapper;

    @Autowired
    BonusCountMapper bonusCountMapper;

    @Autowired
    FreezeAmountMapper freezeAmountMapper;

    @Autowired
    FinanceService financeService;

    @Autowired
    MerchantMapper merchantMapper;

    @Autowired
    SpuAttributeMapper spuAttributeMapper;

    @Autowired
    CategoryMapper categoryMapper;

    @Autowired
    CommentStatisticsMapper commentStatisticsMapper;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    SnapshotMapper snapshotMapper;

    @Autowired
    DaoService daoService;

    @Autowired
    AppointmentSettingMapper appointmentSettingMapper;

    @Autowired
    ShopAmountMapper shopAmountMapper;

    @Autowired
    OrderService orderService;

    @Autowired
    ShopCollectionMapper shopCollectionMapper;

    @Autowired
    SpuStatisticsMapper spuStatisticsMapper;

    @Autowired
    AttributeMapper attributeMapper;

    @Autowired
    CategorySpecMapper categorySpecMapper;

    @Autowired
    CategoryBrandMapper categoryBrandMapper;

    @Autowired
    FreightMapper freightMapper;

    @Autowired
    UnitMapper unitMapper;

    @Autowired
    InviteFirstBuyMapper inviteFirstBuyMapper;

    @Autowired
    KuaidizsService kuaidizsService;

    @Autowired
    CommissionService commissionService;

    @Value("${wx.pay.appId}")
    private String miniAppId;

    @Value("${wx.app.appId}")
    private String appAppId;

    @Override
    public ResultData<BasePageResp<AfterSaleResp>> getAfterSalePage(AfterSalePageReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Long shopId = user.getShopId();
        if (shopId == null) {
            return new ResultData<>(null);
        }
        req.setTenantId(shopId);
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<AfterSaleResp> list = afterSaleMapper.findAllBackPage(req);
        if (CollectionUtils.isEmpty(list)) {
            return PageHelpUtil.buildPage(list, page);
        }

        List<Long> skuIds = new ArrayList<>();
        list.forEach(item -> {
            if (!skuIds.contains(item.getSkuId())) {
                skuIds.add(item.getSkuId());
            }
        });

        // 获取商品sku信息
        List<Sku> skuList = skuMapper.findAllByIds(skuIds);
        Map<Long, Sku> skuMap = new HashMap<>();
        skuList.stream().forEach(item -> skuMap.put(item.getId(), item));
        Map<Long, User> userMap = daoService.getUserMap(list.stream().map(AfterSaleResp::getUserId).collect(Collectors.toList()));
        Map<Long, Orders> ordersMap = daoService.getOrdersMap(list.stream().map(AfterSaleResp::getOrderId).collect(Collectors.toList()));

        list.stream().forEach((item) -> {
            item.setImage(skuMap.get(item.getSkuId()).getImage());
            item.setSpecNames(skuMap.get(item.getSkuId()).getSpecNames());
            item.setSpecValues(skuMap.get(item.getSkuId()).getSpecValues());
            item.setUserNickname(userMap.get(item.getUserId()).getNickname());
            item.setUserAvatar(userMap.get(item.getUserId()).getAvatar());
            item.setTotalPayAmount(ordersMap.get(item.getOrderId()).getTotalPayAmount());
        });

        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public BaseResp editAfterSaleLogistics(AfterSale req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        AfterSale afterSale = afterSaleMapper.selectByPrimaryKey(req.getId());
        if (!user.getShopId().equals(afterSale.getTenantId())) {
            return new BaseResp(ResultCode.NOT_YOUR_MERCHANT);
        }
        if (AfterSaleTypeEnum.EXCHANGE.getType().equals(afterSale.getType())
                && (AfterSaleStatusEnum.CONFIRM.getStatus().equals(afterSale.getStatus()) || AfterSaleStatusEnum.REFUNDED.getStatus().equals(afterSale.getStatus()))
        ) {
            afterSale.setDeliveryLogisticsCompany(req.getDeliveryLogisticsCompany());
            afterSale.setDeliveryLogisticsNumber(req.getDeliveryLogisticsNumber());
            afterSale.setStatus(AfterSaleStatusEnum.REFUNDED.getStatus());
            afterSale.setDealRemark(req.getDealRemark());
            afterSale.setDealTime(new Date());
            afterSaleMapper.updateByPrimaryKeySelective(afterSale);
            return new BaseResp();
        } else {
            return new BaseResp(ResultCode.FAIL);
        }

    }

    @Override
    public BaseResp rejectAfterSale(AfterSale req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        AfterSale afterSale = afterSaleMapper.selectByPrimaryKey(req.getId());
        if (!user.getShopId().equals(afterSale.getTenantId())) {
            return new BaseResp(ResultCode.NOT_YOUR_MERCHANT);
        }

        if (!AfterSaleStatusEnum.REFUNDED.getStatus().equals(afterSale.getStatus())) {
            afterSale.setDealRemark(req.getDealRemark());
            afterSale.setStatus(AfterSaleStatusEnum.REJECT.getStatus());
            afterSale.setDealTime(new Date());
            afterSaleMapper.updateByPrimaryKeySelective(afterSale);
            return new BaseResp();
        } else {
            return new BaseResp(ResultCode.FAIL);
        }
    }

    @Override
    public BaseResp confirmAfterSale(AfterSale req) {
        AfterSale afterSale = afterSaleMapper.selectByPrimaryKey(req.getId());
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (!user.getShopId().equals(afterSale.getTenantId())) {
            return new BaseResp(ResultCode.NOT_YOUR_MERCHANT);
        }

        if (AfterSaleStatusEnum.PROCESSING.getStatus().equals(afterSale.getStatus())) {
            afterSale.setDealRemark(req.getDealRemark());
            afterSale.setStatus(AfterSaleStatusEnum.CONFIRM.getStatus());
            afterSale.setDealTime(new Date());
            afterSaleMapper.updateByPrimaryKeySelective(afterSale);
            return new BaseResp();
        } else {
            return new BaseResp(ResultCode.FAIL);
        }
    }

    @Override
    public ResultData<AfterSaleDetailResp> getAfterSaleDetail(Long id) {
        AfterSale afterSale = afterSaleMapper.selectByPrimaryKey(id);
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (!user.getShopId().equals(afterSale.getTenantId())) {
            return new ResultData<>(null);
        }
        User afterSaleUser = userMapper.selectByPrimaryKey(afterSale.getUserId());
        Orders orders = ordersMapper.findOneByTradeNo(afterSale.getTradeNo());
        Shop shop = shopMapper.selectByPrimaryKey(afterSale.getTenantId());
        AfterSaleDetailResp resp = AfterSaleDetailResp.builder()
                .afterSale(afterSale)
                .orders(orders)
                .orderSku(orderSkuMapper.selectByPrimaryKey(afterSale.getOrderSkuId()))
                .sku(skuMapper.selectByPrimaryKey(afterSale.getSkuId()))
                .spu(spuMapper.selectByPrimaryKey(afterSale.getSpuId()))
                .orderAddress(orderAddressMapper.findOneByOrderId(orders.getId()))
                .tenantName(shop.getShopName())
                .tenantAvatar(shop.getAvatar())
                .userNickname(afterSaleUser.getNickname())
                .userAvatar(afterSaleUser.getAvatar())
                .build();

        return new ResultData(resp);
    }

    @Override
    public BaseResp editOrderLogistics(Orders orders) {
        Orders selectOrders = ordersMapper.selectByPrimaryKey(orders.getId());
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (!user.getShopId().equals(selectOrders.getTenantId())) {
            return new BaseResp(ResultCode.NOT_YOUR_MERCHANT);
        }

        orders.setLogisticsStatus(LogisticsStatusEnum.DONE.getStatus());
        ordersMapper.updateOrderLogistics(orders);
        orderSkuMapper.updateLogisticsStatusByOrderId(LogisticsStatusEnum.DONE.getStatus(), orders.getId());

        //发货解冻
        logisticsService.unFreezeOrder(selectOrders);
        return new BaseResp();
    }

    @Override
    public ResultData<BasePageResp<TenantWithdraw>> getTenantWithdrawPage(PageReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Long shopId = user.getShopId();
        if (shopId == null) {
            return new ResultData<>(null);
        }
        req.setTenantId(user.getShopId());
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<TenantWithdraw> list = tenantWithdrawMapper.findAllPage(req);
        ResultData<BasePageResp<TenantWithdraw>> basePageRespResultData = PageHelpUtil.buildPage(list, page);
        BasePageResp<TenantWithdraw> value = basePageRespResultData.getValue();
        value.setExtra(tenantWithdrawMapper.sumByStatusAndTenantId(TenantWithdrawStatusEnum.SUCCESS.getStatus(), user.getShopId()));
        return basePageRespResultData;
    }

    @Override
    public BaseResp createTenantWithdraw(TenantWithdraw req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        // 判断余额是否足够
        Tenant tenant = tenantMapper.selectByPrimaryKey(user.getShopId());

        BigDecimal sum = tenantWithdrawMapper.sumByStatus(TenantWithdrawStatusEnum.PROCESSING.getStatus());

        if (sum == null) {
            sum = BigDecimal.ZERO;
        }
        //冻结金额
        BigDecimal freeze = freezeAmountMapper.sumAmountByTenantId(user.getShopId()).getTotalFreezeAmount();
        if (tenant.getPoint().subtract(sum).compareTo(req.getAmount()) > -1 && tenant.getPoint().subtract(freeze).subtract(sum).compareTo(req.getAmount()) < 0) {
            return new BaseResp(ResultCode.FREEZE_POINT);
        }

        // 余额减去提现中的，要大于当前要提现的
        if (tenant.getPoint().subtract(sum).compareTo(req.getAmount()) > -1) {
            tenantWithdrawMapper.insert(TenantWithdraw.builder()
                    .tenantId(user.getShopId())
                    .amount(req.getAmount())
                    .status(TenantWithdrawStatusEnum.PROCESSING.getStatus())
                    .createdAt(new Date())
                    .updatedAt(new Date())
                    .build());
        } else {
            return new BaseResp(ResultCode.INSUFFICIENT_BALANCE);
        }
        return new BaseResp();
    }

    @Override
    public ResultData<TenantFundVO> getTenantFundInfo() {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        TenantFundVO vo = new TenantFundVO();
        vo.setCoin(BigDecimal.ZERO);
        vo.setPoint(BigDecimal.ZERO);
        vo.setWithdrawProcessing(BigDecimal.ZERO);
        vo.setTotalFreezeAmount(BigDecimal.ZERO);
        vo.setWithdrawSuccess(BigDecimal.ZERO);
        if (user.getShopId() == null) {
            return new ResultData<>(vo);
        }
        Tenant tenant = tenantMapper.selectByPrimaryKey(user.getShopId());

        if (tenant == null) {
            return new ResultData<>(vo);
        }
        FreezeAmountTotalVO freezeAmountTotalVO = freezeAmountMapper.sumAmountByTenantId(tenant.getId());
        BigDecimal freezeAmount = freezeAmountTotalVO == null ? BigDecimal.ZERO : freezeAmountTotalVO.getTotalFreezeAmount();
        vo.setPoint(tenant.getPoint());
        vo.setCoin(tenant.getCoin());
        vo.setWithdrawProcessing(tenantWithdrawMapper.sumByStatusAndTenantId(TenantWithdrawStatusEnum.PROCESSING.getStatus(), user.getShopId()));
        vo.setWithdrawSuccess(tenantWithdrawMapper.sumByStatusAndTenantId(TenantWithdrawStatusEnum.SUCCESS.getStatus(), user.getShopId()));
        vo.setTotalFreezeAmount(freezeAmount);
        return new ResultData<>(vo);
    }

    @Override
    public ResultData<BasePageResp<TenantFlow>> getBalanceFlowPage(PageReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Long shopId = user.getShopId();
        if (shopId == null) {
            return new ResultData<>(null);
        }
        req.setTenantId(user.getShopId());
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<TenantFlow> list = tenantFlowMapper.findAllPage(req);
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<String> getMerchantAuth(User user) {
        if (user.getShopId() == null) {
            return new ResultData<>("NO_SHOP"); // 您当前还没有绑定的商户
        }

        Boss boss = bossMapper.findOneByShopId(user.getShopId());
        if (boss != null && boss.getUserId().equals(user.getId())) {
            return new ResultData<>("IS_BOSS"); // 可以访问钱包
        } else {
            return new ResultData<>("NOT_BOSS"); // 您当前还没有权限访问商户钱包
        }
    }

    @Override
    public ResultData<MerchantHomeStatisticsVO> getHomeStatistics(HomeStatisticsReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Long tenantId = user.getShopId();
        MerchantHomeStatisticsVO vo = new MerchantHomeStatisticsVO();
        vo.setShop(shopMapper.selectByPrimaryKey(tenantId));
        Date date = new Date();//取时间
        Calendar calendar = Calendar.getInstance();

        ShopStatistics shopStatistics = shopStatisticsMapper.findOneByShopId(user.getShopId());
        Shop shop = shopMapper.selectByPrimaryKey(tenantId);
        Long shopId = shop.getId();
        vo.setShopStatistics(shopStatistics);
        calendar.setTime(date);
        Date todayStart = getDateStart(calendar);
        vo.setTodayOrder(ordersMapper.countByTimeRangeAndTenantId(todayStart, date, tenantId));
        vo.setTotalOrder(ordersMapper.countByTenantId(tenantId));
        vo.setWaitDelivery(ordersMapper.countByStatusAndLogisticsStatusAndTenantIdAndRushBuyStatus(OrdersStatusEnum.PAID.getStatus(), tenantId, RushBuyStatusEnum.SUCCESS.getStatus()));
        vo.setDeliveries(ordersMapper.countByStatusAndDeliveriesAndTenantId(OrdersStatusEnum.PAID.getStatus(), tenantId));
        vo.setAfterSale(afterSaleMapper.countByStatusAndTenantId(AfterSaleStatusEnum.PROCESSING.getStatus(), tenantId));
        vo.setReturnConfirm(afterSaleMapper.countByStatusAndTenantId(AfterSaleStatusEnum.CONFIRM.getStatus(), tenantId));
        BigDecimal todayAmount = ordersMapper.sumByTimeRangeAndTenantId(todayStart, date, tenantId);
        vo.setTodayAmount(todayAmount == null ? BigDecimal.ZERO : todayAmount);
        vo.setTodayRefundCount(ordersMapper.countRefundByTimeRangeAndTenantId(todayStart, date, tenantId));
        SpuStatisticsSumVO sumToday = spuStatisticsMapper.sumPvAndUvByDateAndTenantId(todayStart, date, user.getShopId());
        if (sumToday != null) {
            vo.setTodayPv(sumToday.getPv());
            vo.setTodayUv(sumToday.getUv());
        }
        vo.setTodayCustomerCount(ordersMapper.countUserByTenantIdAndCreatedAtBetween(tenantId, todayStart, date));
        vo.setShopType(shop.getType());

        calendar.setTime(date);
        calendar.add(Calendar.DATE, -1);
        Date yesterdayStart = getDateStart(calendar);
        Date yesterdayEnd = getDateEnd(calendar);
        vo.setYesterdayOrder(ordersMapper.countByTimeRangeAndTenantId(yesterdayStart, yesterdayEnd, tenantId));
        BigDecimal yesterdayAmount = ordersMapper.sumByTimeRangeAndTenantId(yesterdayStart, yesterdayEnd, tenantId);
        vo.setYesterdayAmount(yesterdayAmount == null ? BigDecimal.ZERO : yesterdayAmount);
        vo.setYesterdayRefundCount(ordersMapper.countRefundByTimeRangeAndTenantId(yesterdayStart, yesterdayEnd, tenantId));
        vo.setYesterdayCustomerCount(ordersMapper.countUserByTenantIdAndCreatedAtBetween(tenantId, yesterdayStart, yesterdayEnd));
        SpuStatisticsSumVO sumYesterday = spuStatisticsMapper.sumPvAndUvByDateAndTenantId(yesterdayStart, yesterdayEnd, user.getShopId());
        if (sumYesterday != null) {
            vo.setYesterdayPv(sumYesterday.getPv());
            vo.setYesterdayUv(sumYesterday.getUv());
        }
        vo.setTenantFundVO(getTenantFundInfo().getValue());

        //订单数据统计
        TenantSaleStatisticsVO tenantSaleStatisticsVO = new TenantSaleStatisticsVO();
        Date dateStart = null;
        if (!req.getIsTotal()) {
            Calendar startCalendar = Calendar.getInstance();
            startCalendar.setTime(new Date());
            startCalendar.add(Calendar.DATE, -6);
            dateStart = getDateStart(startCalendar);
        }
        OrderStatisticAmountVO orderStatisticAmountVO = ordersMapper.countByTimeStart(dateStart, shopId);
        tenantSaleStatisticsVO.setOrderCount(orderStatisticAmountVO.getOrderCount());
        tenantSaleStatisticsVO.setSaleAmount(orderStatisticAmountVO.getOrderAmount());
        tenantSaleStatisticsVO.setVisitCount(shopStatistics != null ? shopStatistics.getVisitCount() : 0L);
        tenantSaleStatisticsVO.setCollectionCount(shopCollectionMapper.countByShopId(tenantId));
        vo.setTenantSaleStatistics(tenantSaleStatisticsVO);

        //排名信息
        ShopAmount shopAmount = shopAmountMapper.findOneByShopId(shopId);
        Long totalRank;
        Long sameTotalRank;
        if (shopAmount != null) {
            totalRank = shopAmountMapper.countByAmountGreaterThan(shopAmount.getAmount()) + 1;
            sameTotalRank = shopAmountMapper.countByAmountGreaterThanAndIndustryFirstId(shopAmount.getAmount(), shopAmount.getIndustryFirstId());
        } else {
            totalRank = shopAmountMapper.countAll() + 1;
            sameTotalRank = shopAmountMapper.countByIndustryFirstId(shop.getIndustryFirstId()) + 1;
        }
        vo.setTotalRank(totalRank);
        vo.setSameTotalRank(sameTotalRank);

        return new ResultData<>(vo);
    }

    public Date getDateStart(Calendar calendar) {
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public Date getDateEnd(Calendar calendar) {
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    @Override
    public BaseResp editShopAvatar(Shop req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (isShopMember(user)) {
            shopMapper.updateAvatarById(req.getAvatar(), user.getShopId());
        }
        return new BaseResp();
    }

    @Override
    public BaseResp editShopNickname(Shop req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (isShopMember(user)) {
            shopMapper.updateShopNameById(req.getShopName(), user.getShopId());
        }
        return new BaseResp();
    }

    @Override
    public BaseResp editShopReturnAddress(Shop req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (isShopMember(user)) {
            shopMapper.updateReturnAddressById(req.getReturnAddress(), user.getShopId());
        }
        return new BaseResp();
    }

    @Override
    public BaseResp editShopAfterSaleAddress(Shop req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (isShopMember(user)) {
            shopMapper.updateAfterSaleAddressById(req.getAfterSaleAddress(), user.getShopId());
        }
        return new BaseResp();
    }

    @Override
    public BaseResp editShopAfterSalePhone(Shop req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (isShopMember(user)) {
            shopMapper.updateAfterSalePhoneById(req.getAfterSalePhone(), user.getShopId());
        }
        return new BaseResp();
    }

    private Boolean isShopMember(User user) {

        Shop shop = shopMapper.selectByPrimaryKey(user.getShopId());
        Boolean isBoss = false;
        if (shop == null || (!user.getId().equals(shop.getUserId()))) {
            // 如果不是店长，就判断是否是老板
            Boss boss = bossMapper.findOneByShopId(shop.getId());
            if (boss != null && boss.getUserId().equals(user.getId())) {
                isBoss = true;
            }
        }
        if (shop != null || isBoss) {
            return true;
        } else {
            return false;
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public BaseResp editSpuAndSku(SpuEditVO spuEditVO) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        Spu spu = spuEditVO.getSpu();
        List<Sku> skuList = spuEditVO.getSkuList();
        List<SpuAttribute> spuAttributeList = spuEditVO.getSpuAttributeList();

        Shop shop = shopMapper.selectByPrimaryKey(user.getShopId());
        Category category = categoryMapper.selectByPrimaryKey(spu.getCategoryId());

        spu.setShopId(shop.getId());
        spu.setLatitude(shop.getLatitude());
        spu.setLongitude(shop.getLongitude());
        spu.setIndustryFirstId(shop.getIndustryFirstId());
        spu.setIndustrySecondId(shop.getIndustrySecondId());

        // 批量设置供货价
        for (Sku item : skuList) {

            BigDecimal costPrice = item.getPrice().multiply(BigDecimal.ONE.subtract(shop.getServiceRate())).setScale(2, BigDecimal.ROUND_HALF_DOWN);
            if (item.getCostPrice() == null || item.getCostPrice().compareTo(costPrice) > 0) {
                item.setCostPrice(costPrice);
            }
            // 如果没设置，则设置默认值
            if (item.getChangePrice() == null || item.getChangePrice().compareTo(BigDecimal.ZERO) <= 0) {
                item.setChangePrice(costPrice);
            }
            item.setType(spu.getType());
        }


        spu.setShopId(shop.getId());
        spu.setLatitude(shop.getLatitude());
        spu.setLongitude(shop.getLongitude());
        spu.setIndustryFirstId(shop.getIndustryFirstId());
        spu.setIndustrySecondId(shop.getIndustrySecondId());

        if (ShopTypeEnum.BUSINESS.getType().equals(shop.getType())) {
            spu.setType(SpuTypeEnum.SHOP.getType());
            // fixme 目前先让所有商家的商品都为预约商品
            if (spu.getShopSpuType() == null) {
                spu.setShopSpuType(ShopSpuTypeEnum.APPOINTMENT.getType());
            }
        }

        // 如果主播佣金比例大于30%，则不允许
        if (spu.getAnchorProportion().compareTo(BigDecimal.valueOf(0.3)) > 0) {
            return new BaseResp(ResultCode.SPU_COMMISSION_ERROR);
        }

        if (SpuTypeEnum.NORMAL.getType().equals(spu.getType()) || SpuTypeEnum.EXCHANGE.getType().equals(spu.getType()) || SpuTypeEnum.COMMISSION.getType().equals(spu.getType())) {
            if (spu.getId() == null) {
                if (SpuHiddenEnum.VISIBLE.getType().equals(spu.getHidden())) {
                    // 如果是想上架，则要进入待审核
                    spu.setHidden(SpuHiddenEnum.WAIT_AUDIT.getType());
                }
                spu.setAuditStatus(SpuAuditStatusEnum.WAIT_AUDIT.getAuditStatus());
            }
        } else {
            spu.setAuditStatus(SpuAuditStatusEnum.PASS.getAuditStatus());
        }

        if (spuEditVO.getSpu().getId() == null) {
            // 新建
            spu.setDeleted((byte) 0);
            spu.setSales(0);
            spu.setFiveStar(0);
            spu.setSorts(0);
            spu.setCreatedAt(new Date());
            spu.setUpdatedAt(new Date());
            spu.setRid(category.getRid() != null ? category.getRid() : category.getId());
            spu.setTenantId(user.getShopId());
            if (spu.getLimitCount() == null) {
                spu.setLimitCount(0L);
            }
            if (spu.getFlashHidden() == null) {
                spu.setFlashHidden(ToggleEnum.ON.getStatus());
            }
            spuMapper.insert(spu);

            for (Sku sku : skuList) {
                sku.setSpuId(spu.getId());
                sku.setSales(0);
                sku.setDeleted((byte) 0);
                sku.setCreatedAt(new Date());
                sku.setUpdatedAt(new Date());
                sku.setTenantId(user.getShopId());
                if (sku.getPartnerPrice() == null) {
                    sku.setPartnerPrice(sku.getPrice());
                }
            }
            skuMapper.batchInsert(skuList);

            if (spuAttributeList != null && spuAttributeList.size() > 0) {
                spuAttributeMapper.batchInsert(spuAttributeList, spu.getId());
            }

            // 初始化spu评价统计
            commentStatisticsMapper.insert(new CommentStatistics(null, spu.getId(), 0, 0, 0, 0, 0, 0, 0, 0));
        } else {
            // 编辑
            spu.setUpdatedAt(new Date());
            spu.setTenantId(spu.getShopId());
            spuMapper.updateByPrimaryKeySelective(spu);

            if (spuEditVO.getIsSkuChange()) {
                List<Sku> skuResult = skuMapper.findAllBySpuId(spu.getId());
                Map<String, Sku> skuMap = new HashMap<>();
                skuResult.stream().forEach(item -> skuMap.put(item.getSpecValues(), item));

                // 拆分出删除、插入、更新
                List<Sku> skuDelete = new ArrayList<>();
                List<Sku> skuInsert = new ArrayList<>();
                List<Sku> skuUpdate = new ArrayList<>();

                Map<String, Sku> newSkuMap = new HashMap<>();
                skuList.stream().forEach(item -> {
                    item.setTenantId(spu.getTenantId());
                    if (skuMap.containsKey(item.getSpecValues())) {
                        item.setUpdatedAt(new Date());
                        skuUpdate.add(item);
                    } else {
                        item.setSpuId(spu.getId());
                        item.setSales(0);
                        item.setDeleted((byte) 0);
                        item.setCreatedAt(new Date());
                        item.setUpdatedAt(new Date());
                        skuInsert.add(item);
                    }
                    newSkuMap.put(item.getSpecValues(), item);
                });
                skuResult.forEach(item -> {
                    item.setTenantId(spu.getTenantId());
                    if (!newSkuMap.containsKey(item.getSpecValues())) {
                        skuDelete.add(item);
                    }
                });
                // 先删除，再插入，再更新
                if (!CollectionUtils.isEmpty(skuDelete)) {
                    skuMapper.updateDeletedByIdIn(DeletedEnum.DELETED.getStatus(), skuDelete.stream().map(Sku::getId).collect(Collectors.toList()));
                }
                if (!CollectionUtils.isEmpty(skuInsert)) {
                    skuMapper.batchInsert(skuInsert);
                }
                if (!CollectionUtils.isEmpty(skuUpdate)) {
                    skuMapper.updateBatchSelective(skuUpdate);
                }
            } else {
                // 如果sku只是修改了价格数量，则只更新
                for (Sku sku : skuList) {
                    sku.setTenantId(spu.getTenantId());
                    sku.setUpdatedAt(new Date());
                }
                skuMapper.updateBatchSelective(skuList);
            }

            spuAttributeMapper.deleteBySpuId(spu.getId());
            if (spuAttributeList != null && spuAttributeList.size() > 0) {
                spuAttributeMapper.batchInsert(spuAttributeList, spu.getId());
            }
        }

        // 创建快照
        createSnapshot(spu, spuAttributeList);

        // 删除管理后台缓存
        deleteRedisByKey("AdminProductPage*");
        deleteRedisByKey("HomeInfoResp");
        deleteRedisByKey("AdminSpuPage*");
        deleteRedisByKey("MerchantProductPage:" + user.getShopId() + ":*");
        deleteRedisByKey("MerchantSpuPage:" + user.getShopId() + ":*");
        deleteRedisByKey("SpuPage*");
        deleteRedisByKey("ProductDetail:" + spu.getId() + ":*");
        deleteRedisByKey("SkuList:" + spu.getId() + ":*");
        deleteRedisByKey("LikeSpu:" + spu.getCategoryId());

        //重新统计并保存数据
        Spu existSpu = spuMapper.selectByPrimaryKey(spu.getId());
        saveSpuStatistics(spuEditVO.getSpu(), existSpu.getCategoryId());

        return new BaseResp();
    }

    /**
     * 模糊删除redis，支持通配符
     *
     * @param key
     */
    private void deleteRedisByKey(String key) {
        Set<String> keys = redisTemplate.keys(key);
        if (!CollectionUtils.isEmpty(keys)) {
            redisTemplate.delete(keys);
        }
    }

    /**
     * 创建商品SPU级快照
     * 0.0.1: 初始版本
     *
     * @param spu
     * @param spuAttributes
     */
    private void createSnapshot(Spu spu, List<SpuAttribute> spuAttributes) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        SnapshotDTO snapshotDTO = new SnapshotDTO(spu, spuAttributes);
        Snapshot snapshot = Snapshot.builder()
                .spuId(spu.getId())
                .version("0.0.1")
                .content(JSON.toJSONString(snapshotDTO))
                .createdAt(new Date())
                .tenantId(user.getShopId())
                .build();
        snapshotMapper.insert(snapshot);
    }

    private void saveSpuStatistics(Spu spu, Long categoryId) {
        List<Long> categroyList = new ArrayList<>();
        categroyList.add(categoryId);
        saveSpuStatistics(spu, categroyList);
    }

    private void saveSpuStatistics(Spu spu, List<Long> categoryIds) {
        //添加删除或修改了商品名称就更新统计数据
        ValueOperations<String, List<TagSpuStatisticsVO>> operations = redisTemplate.opsForValue();
        if (spu == null || spu.getName() != null) {
            //标题总字数
            List<StatisticsCountVO> totalWordCounts = spuMapper.getTotalWordCountByCategoryIds(categoryIds);
            Map<Long, Long> totalWordCountMap = new HashMap<>();
            if (!org.apache.commons.collections.CollectionUtils.isEmpty(totalWordCounts)) {
                totalWordCounts.stream().forEach(item -> {
                    totalWordCountMap.put(item.getId(), item.getCount());
                });
            }

            //博文总数
            List<StatisticsCountVO> itemCount = spuMapper.getItemCountByCategoryIds(categoryIds);
            Map<Long, Long> itemCountMap = new HashMap<>();
            if (!org.apache.commons.collections.CollectionUtils.isEmpty(itemCount)) {
                itemCount.stream().forEach(item -> {
                    itemCountMap.put(item.getId(), item.getCount());
                });
            }

            //计算统计数量
            List<TagSpuStatisticsVO> voList = new ArrayList<>();
            totalWordCounts.stream().forEach(item -> {
                TagSpuStatisticsVO vo = new TagSpuStatisticsVO();
                vo.setType(UserTagTypeEnum.SPU.getType());
                vo.setRelateId(item.getId());
                vo.setItemCount(itemCountMap.get(item.getId()));
                vo.setUpdateAt(new Date());
                vo.setTotalWordCount(totalWordCountMap.get(item.getId()));
                voList.add(vo);
            });

            if (operations.get("tfidf" + UserTagTypeEnum.SPU.getType()) != null) {
                //更新下架的类目统计
                List<TagSpuStatisticsVO> statisticsVO = operations.get("tfidf" + UserTagTypeEnum.SPU.getType());
                statisticsVO = statisticsVO.stream().filter(Objects::nonNull).collect(Collectors.toList());
                List<Long> relateIds = statisticsVO.stream().map(TagSpuStatisticsVO::getRelateId).collect(Collectors.toList());
                List<TagSpuStatisticsVO> addStatistics = new ArrayList<>();

                Map<Long, TagSpuStatisticsVO> statisticsVOMap = new HashMap<>();
                statisticsVO.stream().forEach(item -> {
                    statisticsVOMap.put(item.getRelateId(), item);
                });

                voList.stream().forEach(item -> {
                    if (relateIds.contains(item.getRelateId())) {
                        BeanUtils.copyProperties(item, statisticsVOMap.get(item.getRelateId()));
                    } else {
                        addStatistics.add(item);
                    }
                });
                if (!CollectionUtils.isEmpty(addStatistics)) {
                    statisticsVO.addAll(addStatistics);
                }
                operations.set("tfidf" + UserTagTypeEnum.SPU.getType(), statisticsVO);
            }
        }
    }

    @Override
    public ResultData<List<Freight>> getFreightList() {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        return new ResultData<>(freightMapper.findAllByTenantId(user.getShopId()));
    }

    @Override
    public ResultData<List<Category>> getAllCategoryList(Byte type) {
        ValueOperations<String, List<Category>> operations = redisTemplate.opsForValue();
        String key = "GetAllCategoryList:" + type.toString();
        List<Category> result = operations.get(key);
        if (result == null) {
            result = categoryMapper.findAllByType(type);
            operations.set(key, result);
        }
        return new ResultData<>(result);
    }

    @Override
    public ResultData<List<Category>> getChildrenCategory(Long id) {
        return new ResultData<>(categoryMapper.findAllByPid(id));
    }

    @Override
    public ResultData<List<Category>> getRootCategoryList(Byte type) {
        ValueOperations<String, List<Category>> operations = redisTemplate.opsForValue();
        String key = "GetRootCategoryList:" + type.toString();
        List<Category> result = operations.get(key);
        if (result == null) {
            result = categoryMapper.findAllRootByType(type);
            operations.set(key, result);
        }
        return new ResultData<>(result);
    }

    public boolean computedIsUseCache(SpuReq req) {
        // 只缓存首页，并且没有搜索其他内容
        return req.getPageNo() == 1 && req.getCategoryId() == null && req.getHidden() == null && req.getIsVirtual() == null && req.getName() == null && req.getBrandId() == null;
    }

    @Override
    public ResultData<List<Unit>> getUnitList() {
        return new ResultData<>(unitMapper.findAll());
    }

    @Override
    public ResultData<BasePageResp<SpuResp>> getSpuPage(SpuReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (user.getShopId() == null) {
            return new ResultData<>();
        }

        boolean isUseCache = computedIsUseCache(req);
        ValueOperations<String, ResultData<BasePageResp<SpuResp>>> operations = redisTemplate.opsForValue();
        String key = "MerchantSpuPage:" + user.getShopId() + ":" + DigestUtils.md5DigestAsHex((JSON.toJSONString(req)).getBytes());
        if (isUseCache) {
            ResultData<BasePageResp<SpuResp>> result = operations.get(key);
            if (result != null) {
                return result;
            }
        }

        req.setTenantId(user.getShopId());
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<SpuResp> list = spuMapper.findAllAdminPage(req);
        if (CollectionUtils.isEmpty(list)) {
            return PageHelpUtil.buildPage(list, page);
        }

        Map<Long, Category> categoryMap = daoService.getCategoryMap(list.stream().map(Spu::getCategoryId).collect(Collectors.toList()));
        Map<Long, Brand> brandMap = daoService.getBrandMap(list.stream().map(Spu::getBrandId).collect(Collectors.toList()));
        Map<Long, Freight> freightMap = daoService.getFreightMap(list.stream().map(Spu::getFreightId).collect(Collectors.toList()));
        // 佣金
        Map<Long, SpuCommission> spuCommissionMap = daoService.getSpuCommissionMap(list.stream().map(Spu::getId).collect(Collectors.toList()));

        //总库存统计
        List<Sku> allSku = skuMapper.findAllBySpuIds(list.stream().map(SpuResp::getId).collect(Collectors.toList()));
        Map<Long, Integer> spuStockMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(allSku)) {
            allSku.stream().forEach(item -> {
                Integer stock = spuStockMap.get(item.getSpuId());
                if (stock == null) {
                    spuStockMap.put(item.getSpuId(), item.getStock());
                } else {
                    spuStockMap.put(item.getSpuId(), item.getStock() + stock);
                }
            });
        }

        list.stream().forEach((item) -> {
            item.setCategoryTitle(categoryMap.get(item.getCategoryId()).getTitle());
            item.setBrandName(brandMap.containsKey(item.getBrandId()) ? brandMap.get(item.getBrandId()).getName() : null);
            item.setFreightName(freightMap.get(item.getFreightId()).getName());
            item.setSpuCommission(spuCommissionMap.get(item.getId()));
            item.setTotalStock(spuStockMap.get(item.getId()));
        });

        ResultData<BasePageResp<SpuResp>> result = PageHelpUtil.buildPage(list, page);

        //spu统计数据
        SpuAuditCountVO countVO = new SpuAuditCountVO();
        req.setShopId(user.getShopId());
        countVO.setTotalCount(spuMapper.countByParam(req));
        countVO.setPassCount(spuMapper.countByAuditStatusAndParam(SpuAuditStatusEnum.PASS.getAuditStatus(), req));
        countVO.setRefuseCount(spuMapper.countByAuditStatusAndParam(SpuAuditStatusEnum.REFUSE.getAuditStatus(), req));
        countVO.setWaitAuditCount(spuMapper.countByAuditStatusAndParam(SpuAuditStatusEnum.WAIT_AUDIT.getAuditStatus(), req));
        result.getValue().setExtra(countVO);

        if (isUseCache) {
            operations.set(key, result, 10, TimeUnit.MINUTES);
        }
        return result;
    }

    @Override
    public ResultData<SpuEditVO> getSpuEditDetail(Long id) {
        SpuEditVO spuEditVO = new SpuEditVO();
        Spu spu = spuMapper.selectByPrimaryKey(id);
        Category category = categoryMapper.selectByPrimaryKey(spu.getCategoryId());
        List<Category> categoryList = new ArrayList<>();
        if (category.getLevel().equals(2)) {
            Category parentCategory = categoryMapper.selectByPrimaryKey(category.getPid());
            Category rootCategory = categoryMapper.selectByPrimaryKey(category.getRid());
            categoryList.add(rootCategory);
            categoryList.add(parentCategory);
            categoryList.add(category);
        } else if (category.getLevel().equals(1)) {
            Category parentCategory = categoryMapper.selectByPrimaryKey(category.getPid());
            categoryList.add(parentCategory);
            categoryList.add(category);
        } else {
            categoryList.add(category);
        }

        spuEditVO.setCategoryList(categoryList);
        spuEditVO.setSpu(spu);
        spuEditVO.setSkuList(skuMapper.findAllBySpuId(id));
        spuEditVO.setSpuAttributeList(spuAttributeMapper.findAllBySpuId(id));
        return new ResultData<>(spuEditVO);
    }

    @Override
    public BaseResp deleteProduct(Long id) {
        Spu spu = spuMapper.selectByPrimaryKey(id);

        //更新商品统计数据
        saveSpuStatistics(null, spu.getCategoryId());

        //如果是预约商品删除设置
        if (ShopSpuTypeEnum.APPOINTMENT.getType().equals(spu.getShopSpuType())) {
            appointmentSettingMapper.updateDeletedBySpuId(DeletedEnum.DELETED.getStatus(), spu.getId());
        }

        spuMapper.updateDeletedById(DeletedEnum.DELETED.getStatus(), id);
        skuMapper.updateDeletedBySpuId(DeletedEnum.DELETED.getStatus(), id);
        // 删除管理后台缓存
        deleteRedisByKey("MerchantProductPage:" + spu.getShopId() + ":*");
        deleteRedisByKey("MerchantSpuPage:" + spu.getShopId() + ":*");
        deleteRedisByKey("SpuPage*");
        deleteRedisByKey("ProductDetail:" + spu.getId() + ":*");
        deleteRedisByKey("SkuList:" + spu.getId() + ":*");
        return new BaseResp();
    }

    @Override
    public BaseResp editSkuStock(EditSkuStockReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();


        List<EditSkuStockVO> items = req.getItems();
        Map<Long, Sku> skuMap = daoService.getSkuMap(items.stream().map(EditSkuStockVO::getSkuId).collect(Collectors.toList()));
        List<EditSkuStockVO> updateItems = new ArrayList<>();
        items.stream().forEach(item -> {
            if (skuMap.get(item.getSkuId()).getTenantId().equals(user.getShopId())) {
                updateItems.add(item);
            }
        });

        Sku sku = skuMap.get(items.get(0).getSkuId());
        if (!CollectionUtils.isEmpty(updateItems)) {
            // 只有自己人，才可以修改
            if (sku.getTenantId().equals(user.getShopId())) {
                skuMapper.updateBatchStock(updateItems);
                // 删除管理后台缓存
                deleteRedisByKey("MerchantProductPage:" + sku.getTenantId() + ":*");
                deleteRedisByKey("MerchantSpuPage:" + sku.getTenantId() + ":*");
                deleteRedisByKey("SpuPage*");
                deleteRedisByKey("ProductDetail:" + sku.getSpuId() + ":*");
                deleteRedisByKey("SkuList:" + sku.getSpuId() + ":*");
            }
        }
        return new BaseResp();
    }

    @Override
    public BaseResp editSingleSkuStock(Long skuId, Integer stock) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Sku sku = skuMapper.selectByPrimaryKey(skuId);
        if (sku.getTenantId().equals(user.getShopId())) {
            skuMapper.updateStockById(stock, skuId);
        }
        return new BaseResp();
    }

    @Override
    public BaseResp editSkuPrice(EditSkuPriceReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        List<EditSkuPriceVO> items = req.getList();
        Sku sku = skuMapper.selectByPrimaryKey(items.get(0).getSkuId());
        Spu spu = spuMapper.selectByPrimaryKey(sku.getSpuId());

        if (SpuTypeEnum.NORMAL.getType().equals(spu.getType()) || SpuTypeEnum.EXCHANGE.getType().equals(spu.getType()) || SpuTypeEnum.COMMISSION.getType().equals(spu.getType())) {
            if (SpuHiddenEnum.VISIBLE.getType().equals(spu.getHidden())) {
                // 如果是想上架，则要进入待审核
                spu.setHidden(SpuHiddenEnum.WAIT_AUDIT.getType());
                spuMapper.updateByPrimaryKeySelective(spu);
            }
        }

        Shop shop = shopMapper.selectByPrimaryKey(spu.getShopId());
        Map<Long, Sku> skuMap = daoService.getSkuMap(items.stream().map(EditSkuPriceVO::getSkuId).collect(Collectors.toList()));
        if (!CollectionUtils.isEmpty(skuMap.values())) {
            List<EditSkuPriceVO> updateItems = new ArrayList<>();

            //是否为当前店铺下商品
            items.stream().forEach(item -> {
                if (skuMap.get(item.getSkuId()).getTenantId().equals(user.getShopId())) {
                    // 批量设置供货价
                    BigDecimal costPrice = item.getPrice().multiply(BigDecimal.ONE.subtract(shop.getServiceRate())).setScale(2, BigDecimal.ROUND_HALF_DOWN);
                    if (item.getCostPrice() == null || item.getCostPrice().compareTo(costPrice) > 0) {
                        item.setCostPrice(costPrice);
                    }
                    updateItems.add(item);
                }
            });

            if (!CollectionUtils.isEmpty(updateItems)) {
                skuMapper.updateBatchPrice(updateItems);
                List<Sku> skus = skuMapper.findAllBySpuId(spu.getId());
                Collections.sort(skus, (o1, o2) -> o1.getPrice().compareTo(o2.getPrice()));
                spu.setMinPrice(updateItems.get(updateItems.size() - 1).getPrice());
                spu.setMaxPrice(updateItems.get(0).getPrice());
                spuMapper.updateByPrimaryKey(spu);

                // 删除管理后台缓存
                deleteRedisByKey("MerchantProductPage:" + spu.getShopId() + ":*");
                deleteRedisByKey("MerchantSpuPage:" + spu.getShopId() + ":*");
                deleteRedisByKey("SpuPage*");
                deleteRedisByKey("ProductDetail:" + spu.getId() + ":*");
                deleteRedisByKey("SkuList:" + spu.getId() + ":*");
            }
        }
        return new BaseResp();
    }

    @Override
    public BaseResp editChangePrice(EditChangePriceReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Spu spu = spuMapper.selectByPrimaryKey(req.getSpuId());
        if (spu.getTenantId().equals(user.getShopId())) {
            List<Sku> skuList = req.getSkuList();
            if (!CollectionUtils.isEmpty(skuList)) {
                spuMapper.updateAuditStatusAndAuditMessageById(SpuAuditStatusEnum.WAIT_AUDIT.getAuditStatus(), null, req.getSpuId());
                skuMapper.updateBatchChangePrice(skuList);
            }
        }
        return new BaseResp();
    }

    @Override
    public BaseResp editSpuField(SpuFiledReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Spu spu = spuMapper.selectByPrimaryKey(req.getSpuId());
        if (!user.getShopId().equals(spu.getTenantId())) {
            return new BaseResp(ResultCode.NOT_SHOP_MEMBER);
        }
        switch (req.getField()) {
            case "imageList":
                spuMapper.updateImageListById(req.getValue(), req.getSpuId());
                break;
            case "content":
                spuMapper.updateContentById(req.getValue(), req.getSpuId());
                break;
            case "video":
                spuMapper.updateVideoById(req.getValue(), req.getSpuId());
                break;
            default:
                break;
        }

        // 删除管理后台缓存
        deleteRedisByKey("MerchantProductPage:" + spu.getShopId() + ":*");
        deleteRedisByKey("MerchantSpuPage:" + spu.getShopId() + ":*");
        deleteRedisByKey("SpuPage*");
        deleteRedisByKey("ProductDetail:" + spu.getId() + ":*");
        deleteRedisByKey("SkuList:" + spu.getId() + ":*");
        return new BaseResp();
    }

    @Override
    public ResultData<BasePageResp<ShopAmountVO>> getShopAmountPage(ShopAmountReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (req.getIndustryFirstId() != null) {
            req.setIndustryFirstId(shopMapper.selectByPrimaryKey(user.getShopId()).getIndustryFirstId());
        }
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<ShopAmountVO> list = shopAmountMapper.findAllPage(req);
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, Shop> shopMap = daoService.getShopMap(list.stream().map(ShopAmountVO::getShopId).collect(Collectors.toList()));
            List<Long> industryId = list.stream().map(ShopAmountVO::getIndustryFirstId).collect(Collectors.toList());
            industryId.addAll(list.stream().map(ShopAmountVO::getIndustrySecondId).collect(Collectors.toList()));
            Map<Long, Industry> industryMap = daoService.getIndustryMap(industryId);
            list.stream().forEach(item -> {
                item.setShopName(shopMap.get(item.getShopId()).getShopName());
                item.setShopAvatar(shopMap.get(item.getShopId()).getAvatar());
                item.setIndustryFirstName(industryMap.get(item.getIndustryFirstId()).getName());
                item.setIndustrySecondName(industryMap.get(item.getIndustrySecondId()).getName());
            });
        }
        ResultData<BasePageResp<ShopAmountVO>> result = PageHelpUtil.buildPage(list, page);
        ShopAmountRankVO rankVO = new ShopAmountRankVO();
        ShopAmount shopAmount = shopAmountMapper.findOneByShopId(user.getShopId());
        if (req.getIndustryFirstId() == null) {
            Long totalRank;
            if (shopAmount != null) {
                totalRank = shopAmountMapper.countByAmountGreaterThan(shopAmount.getAmount()) + 1;
            } else {
                totalRank = shopAmountMapper.countAll() + 1;
            }
            rankVO.setRank(totalRank);
            rankVO.setAmount(shopAmount != null ? shopAmount.getAmount() : new BigDecimal(BigInteger.ZERO));
        } else {
            Long sameTotalRank;
            if (shopAmount != null) {
                sameTotalRank = shopAmountMapper.countByAmountGreaterThanAndIndustryFirstId(shopAmount.getAmount(), shopAmount.getIndustryFirstId()) + 1;
            } else {
                sameTotalRank = shopAmountMapper.countByIndustryFirstId(req.getIndustryFirstId()) + 1;
            }
            rankVO.setRank(sameTotalRank);
            rankVO.setAmount(shopAmount != null ? shopAmount.getAmount() : new BigDecimal(BigInteger.ZERO));
        }
        result.getValue().setExtra(rankVO);
        return result;
    }

    @Override
    public ResultData<BasePageResp<OrderResp>> getAmountOrderPage(OrderPageReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (user.getShopId() == null) {
            return new ResultData<>();
        }
        req.setTenantId(user.getShopId());
        ResultData<BasePageResp<OrderResp>> shopOrderPage = orderService.getShopOrderPage(user, req);
        OrdersExtraVO vo = new OrdersExtraVO();
        ShopAmount shopAmount = shopAmountMapper.findOneByShopId(user.getShopId());
        List<OrderResp> data = shopOrderPage.getValue().getData();
        BigDecimal totalPay = data.stream().map(OrderResp::getTotalPayAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal totalRefund = data.stream().map(OrderResp::getTotalRefundAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        vo.setSumAmount(totalPay.subtract(totalRefund));
        vo.setTotalAmount(shopAmount != null ? shopAmount.getAmount() : new BigDecimal(BigInteger.ZERO));
        shopOrderPage.getValue().setExtra(vo);
        return shopOrderPage;
    }

    @Override
    public ResultData<List<StatisticsVO>> getMonthAmountOrderList(OrderMonthStatisticsReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Date year = req.getYear();
        Calendar startCalendar = Calendar.getInstance();
        Calendar endCalendar = Calendar.getInstance();
        startCalendar.setTime(year);
        startCalendar.set(Calendar.DAY_OF_YEAR, startCalendar.getActualMinimum(Calendar.DAY_OF_YEAR));
        endCalendar.setTime(year);
        endCalendar.add(Calendar.YEAR, +1);
        endCalendar.set(Calendar.DAY_OF_YEAR, endCalendar.getActualMinimum(Calendar.DAY_OF_YEAR));
        List<StatisticsVO> list = new ArrayList<>();
        if (user.getShopId() != null) {
            list = ordersMapper.getOrderMonthStatistics(getFirstTime(startCalendar).getTime(), getFirstTime(endCalendar).getTime(), user.getShopId());
        }
        return new ResultData<>(list);
    }

    private Calendar getFirstTime(Calendar calendar) {
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        return calendar;
    }

    @Override
    public BaseResp editProductHidden(Long id) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        Spu spu = spuMapper.selectByPrimaryKey(id);
        if (!spu.getTenantId().equals(user.getShopId())) {
            return new BaseResp(ResultCode.NOT_YOUR_MERCHANT);
        }
        if (HiddenEnum.PLATFORM_HIDDEN.getRemark().equals(spu.getHidden())) {
            return new BaseResp(ResultCode.PLATFORM_HIDDEN);
        }
        if (HiddenEnum.VISIBLE.getStatus().equals(spu.getHidden())) {
            spuMapper.updateHiddenById(HiddenEnum.HIDDEN.getStatus(), id);
            skuMapper.updateHiddenBySpuId(HiddenEnum.HIDDEN.getStatus(), id);
        }
        if (HiddenEnum.HIDDEN.getStatus().equals(spu.getHidden())) {
            spuMapper.updateHiddenById(HiddenEnum.VISIBLE.getStatus(), id);
            skuMapper.updateHiddenBySpuId(HiddenEnum.VISIBLE.getStatus(), id);
        }

        //更新商品统计数据
        saveSpuStatistics(null, spu.getCategoryId());

        // 删除管理后台缓存
        deleteRedisByKey("MerchantProductPage:" + user.getShopId() + ":*");
        deleteRedisByKey("MerchantSpuPage:" + user.getShopId() + ":*");
        deleteRedisByKey("SpuPage*");
        return new BaseResp();
    }

    @Override
    public ResultData<String> getLogisticsTrace(User user, Long orderId) {
        Orders orders = ordersMapper.selectByPrimaryKey(orderId);
        if (orders.getTenantId().equals(user.getShopId())) {
            try {
                OrderAddress orderAddress = orderAddressMapper.findOneByOrderId(orderId);
                String result = logisticsService.getOrderTracesByJson(orders.getTradeNo(), orders.getLogisticsCompany(), orders.getLogisticsNumber(), orderAddress.getPhone());
                return new ResultData<>(result);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return new ResultData<>("[]");
    }

    @Override
    public ResultData<OrderStatisticsVO> getOrderStatisticsByYear(Integer year) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        OrderStatisticsVO vo = new OrderStatisticsVO();
        if (user.getShopId() != null) {
            Calendar startCalendar = Calendar.getInstance();
            Calendar endCalendar = Calendar.getInstance();
            startCalendar.set(Calendar.YEAR, year);
            startCalendar.set(Calendar.DAY_OF_YEAR, startCalendar.getActualMinimum(Calendar.DAY_OF_YEAR));
            endCalendar.set(Calendar.YEAR, year + 1);
            endCalendar.set(Calendar.DAY_OF_YEAR, endCalendar.getActualMinimum(Calendar.DAY_OF_YEAR));
            Date start = getFirstTime(startCalendar).getTime();
            Date end = getFirstTime(endCalendar).getTime();
            vo.setStatisticsVOList(ordersMapper.getOrderStatisticsByYear(start, end, user.getShopId()));
            vo.setYearAmouut(ordersMapper.sumAmountByTimeRange(start, end, user.getShopId()));
            vo.setTotalAmount(ordersMapper.sumCompleteAmount(user.getShopId()));
        }
        return new ResultData<>(vo);
    }


    @Override
    public ResultData<SpuSellStatisticsVO> getSpuSellStatistics(SpuSellStatisticsReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Spu spu = spuMapper.selectByPrimaryKey(req.getSpuId());
        SpuSellStatisticsVO vo = new SpuSellStatisticsVO();
        if (spu.getTenantId().equals(user.getShopId())) {
            SpuSellStatisticsVO sellVO = orderSkuMapper.getSpuSellStatistics(req);
            if (sellVO != null) {
                vo.setOrderCount(sellVO.getOrderCount());
                vo.setPayAmount(sellVO.getPayAmount());
                vo.setTenantAmount(sellVO.getTenantAmount());
                vo.setPayNumber(sellVO.getPayNumber());
            }
            SpuSellStatisticsVO refundVO = afterSaleMapper.getSpuRefundStatistics(req);
            if (refundVO != null) {
                vo.setRefundCount(refundVO.getRefundCount());
                vo.setRefundAmount(refundVO.getRefundAmount());
                vo.setRefundNumber(refundVO.getRefundNumber());
            }
            SpuStatisticsSumVO sumVO = spuStatisticsMapper.getSpuStatisticsByTime(spu.getId(), req.getStartTime(), req.getEndTime());
            vo.setUv(sumVO == null ? 0 : sumVO.getUv());
            vo.setPv(sumVO == null ? 0 : sumVO.getPv());
            CommentStatistics commentStatistics = commentStatisticsMapper.findOneBySpuId(req.getSpuId());
            if (commentStatistics != null) {
                Integer likeCount = commentStatistics.getFive() + commentStatistics.getFour() + commentStatistics.getDefaultFive();
                Integer total = commentStatistics.getTotal();
                if (total != 0) {
                    vo.setLikeRate(new BigDecimal(likeCount).divide(new BigDecimal(total).setScale(4, BigDecimal.ROUND_UP)));
                }
            }
        }
        return new ResultData<>(vo);
    }

    @Override
    public ResultData<BasePageResp<Category>> getCategoryPage(CategoryReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<Category> list = categoryMapper.findAllAdminPage(req);
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<CategoryInfoResp> getCategoryInfo(Long id) {
        CategoryInfoResp resp = new CategoryInfoResp();
        resp.setAttributeList(attributeMapper.findAllByCategoryId(id));
        resp.setSpecList(categorySpecMapper.findAllSpecByCategoryId(id));
        resp.setBrandList(categoryBrandMapper.findAllBrandByCategoryId(id));
        return new ResultData<>(resp);
    }

    @Override
    public ResultData<ShopStatisticsDataVO> getShopStatisticsData(TimeRangeReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        req.setTenantId(user.getShopId());
        ShopStatisticsDataVO vo = new ShopStatisticsDataVO();
        OrderStatisticAmountVO amountVO = orderSkuMapper.getShopStatisticsData(req);
        vo.setAmount(amountVO.getOrderAmount());
        vo.setOrderCount(amountVO.getOrderCount());
        vo.setCount(orderSkuMapper.getUserCount(req));
        vo.setRefundAmount(afterSaleMapper.getShopStatisticsData(req));
        SpuStatisticsSumVO shopStatisticsData = spuStatisticsMapper.getShopStatisticsData(req);
        vo.setPv(shopStatisticsData.getPv());
        vo.setUv(shopStatisticsData.getUv());
        return new ResultData<>(vo);
    }


    /**
     * 数据为空 塞入0
     *
     * @param req
     * @param voList
     * @return
     */
    private List<StatisticsVO> supplementData(TimeRangeReq req, List<StatisticsVO> voList, Byte timeType) {
        try {


            Calendar startCalendar = Calendar.getInstance();
            startCalendar.setTime(req.getStartTime());
            Calendar endCalendar = Calendar.getInstance();
            endCalendar.setTime(req.getEndTime());
            if (TimeType.DAY.getType().equals(timeType)) {
                List<String> dates = findDates(req.getStartTime(), req.getEndTime());
                List<String> dateList = voList.stream().map(StatisticsVO::getDate).collect(Collectors.toList());
                dates.stream().forEach(item -> {
                    if (!dateList.contains(item)) {
                        voList.add(StatisticsVO.builder()
                                .date(item)
                                .statisticsMoney(BigDecimal.ZERO)
                                .statisticsNumber(0)
                                .build());
                    }
                });
                Collections.sort(voList, (o1, o2) -> {
                    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                    try {
                        return format.parse(o1.getDate()).compareTo(format.parse(o2.getDate()));
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    return 0;
                });
            }
            if (TimeType.HOUR.getType().equals(timeType)) {
                Integer start = startCalendar.get(Calendar.HOUR_OF_DAY);
                Integer end = endCalendar.get(Calendar.HOUR_OF_DAY);
                List<Integer> list = voList.stream().map(StatisticsVO::getDate).collect(Collectors.toList()).stream().map(Integer::parseInt).collect(Collectors.toList());
                for (Integer i = start; i <= end; i++) {
                    if (!list.contains(i)) {
                        voList.add(StatisticsVO.builder()
                                .date(i.toString())
                                .statisticsMoney(BigDecimal.ZERO)
                                .statisticsNumber(0)
                                .build());
                    }
                }
                Collections.sort(voList, Comparator.comparingInt(o -> Integer.valueOf(o.getDate())));
            }

            return voList;
        } catch (ParseException e) {
            e.printStackTrace();
            log.info(e.getMessage());
        }
        return null;
    }


    /**
     * @param dBegin
     * @param dEnd
     * @return
     * @throws ParseException
     */
    private List<String> findDates(Date dBegin, Date dEnd) throws ParseException {
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        Calendar calBegin = Calendar.getInstance();
        calBegin.setTime(dBegin);

        Calendar calEnd = Calendar.getInstance();
        calEnd.setTime(dEnd);

        List<String> Datelist = new ArrayList<>();
        Datelist.add(format.format(calBegin.getTime()));
        while (dEnd.after(calBegin.getTime())) {
            calBegin.add(Calendar.DATE, 1);
            Datelist.add(format.format(calBegin.getTime()));
        }

        return Datelist;
    }


    @Override
    public ResultData<SpuTrendVO> getSpuClickTrend(TimeRangeReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        SpuTrendVO vo = new SpuTrendVO();
        req.setEndTime(new Date());
        List<StatisticsVO> todayStatistics = spuStatisticsMapper.getSpuClickTrend(req, user.getShopId());
        supplementData(req, todayStatistics, req.getTimeType());
        vo.setTodayStatistics(todayStatistics);
        if (TimeType.HOUR.getType().equals(req.getTimeType())) {
            List<StatisticsVO> yesterdayStatistics = spuStatisticsMapper.getSpuClickTrend(getYesterdayRange(req), user.getShopId());
            supplementData(req, yesterdayStatistics, req.getTimeType());
            vo.setYesterdayStatistics(yesterdayStatistics);
        }
        return new ResultData<>(vo);
    }

    @Override
    public ResultData<SpuTrendVO> getSpuVisitorTrend(TimeRangeReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        SpuTrendVO vo = new SpuTrendVO();
        req.setEndTime(new Date());
        List<StatisticsVO> todayStatistics = spuStatisticsMapper.getSpuVisitorTrend(req, user.getShopId());
        supplementData(req, todayStatistics, req.getTimeType());
        vo.setTodayStatistics(todayStatistics);
        if (TimeType.HOUR.getType().equals(req.getTimeType())) {
            List<StatisticsVO> yesterdayStatistics = spuStatisticsMapper.getSpuVisitorTrend(getYesterdayRange(req), user.getShopId());
            supplementData(req, yesterdayStatistics, req.getTimeType());
            vo.setYesterdayStatistics(yesterdayStatistics);
        }
        return new ResultData<>(vo);
    }

    @Override
    public ResultData<SpuTrendVO> getSpuRefundCountTrend(TimeRangeReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        SpuTrendVO vo = new SpuTrendVO();
        req.setEndTime(new Date());
        List<StatisticsVO> todayStatistics = afterSaleMapper.getSpuRefundTrend(req, user.getShopId());
        supplementData(req, todayStatistics, req.getTimeType());
        vo.setTodayStatistics(todayStatistics);
        if (TimeType.HOUR.getType().equals(req.getTimeType())) {
            List<StatisticsVO> yesterdayStatistics = afterSaleMapper.getSpuRefundTrend(getYesterdayRange(req), user.getShopId());
            supplementData(req, yesterdayStatistics, req.getTimeType());
            vo.setYesterdayStatistics(yesterdayStatistics);
        }
        return new ResultData<>(vo);
    }

    @Override
    public ResultData<SpuTrendVO> getSpuCompleteTrend(TimeRangeReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        SpuTrendVO vo = new SpuTrendVO();
        req.setEndTime(new Date());
        List<StatisticsVO> todayStatistics = orderSkuMapper.getSpuCompleteTrend(req, user.getShopId());
        supplementData(req, todayStatistics, req.getTimeType());
        vo.setTodayStatistics(todayStatistics);
        if (TimeType.HOUR.getType().equals(req.getTimeType())) {
            List<StatisticsVO> yesterdayStatistics = orderSkuMapper.getSpuCompleteTrend(getYesterdayRange(req), user.getShopId());
            supplementData(req, yesterdayStatistics, req.getTimeType());
            vo.setYesterdayStatistics(yesterdayStatistics);
        }
        return new ResultData<>(vo);
    }

    @Override
    public ResultData<SpuTrendVO> getSpuCustomerTrend(TimeRangeReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        SpuTrendVO vo = new SpuTrendVO();
        req.setEndTime(new Date());
        List<StatisticsVO> todayStatistics = orderSkuMapper.getSpuCustomerTrend(req, user.getShopId());
        supplementData(req, todayStatistics, req.getTimeType());
        vo.setTodayStatistics(todayStatistics);
        if (TimeType.HOUR.getType().equals(req.getTimeType())) {
            List<StatisticsVO> yesterdayStatistics = orderSkuMapper.getSpuCustomerTrend(getYesterdayRange(req), user.getShopId());
            supplementData(req, yesterdayStatistics, req.getTimeType());
            vo.setYesterdayStatistics(yesterdayStatistics);
        }
        return new ResultData<>(vo);
    }

    private TimeRangeReq getYesterdayRange(TimeRangeReq req) {
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(req.getStartTime());
        startCalendar.add(Calendar.DATE, -1);
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(req.getEndTime());
        endCalendar.add(Calendar.DATE, -1);
        req.setStartTime(startCalendar.getTime());
        req.setEndTime(endCalendar.getTime());
        return req;
    }

    @Override
    public ResultData<ShopStatisticsDataVO> getSpuRateData(TimeRangeReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        req.setTenantId(user.getShopId());
        ShopStatisticsDataVO vo = new ShopStatisticsDataVO();
        OrderStatisticAmountVO amountVO = orderSkuMapper.getShopStatisticsData(req);
        SpuStatisticsSumVO shopStatisticsData = spuStatisticsMapper.getShopStatisticsData(req);
        BigDecimal amount = amountVO.getOrderAmount() == null ? BigDecimal.ZERO : amountVO.getOrderAmount();
        Long orderCount = amountVO.getOrderCount();
        Long pv = shopStatisticsData == null ? 0 : shopStatisticsData.getPv();
        vo.setAmount(amount);
        vo.setRefundAmount(afterSaleMapper.getShopStatisticsData(req));
        vo.setPv(pv);
        if (pv != null && pv != 0) {
            vo.setThousandsViewAmount(amount.divide(new BigDecimal(pv), 2, BigDecimal.ROUND_UP).multiply(new BigDecimal("1000")));
            vo.setViewPayRate(new BigDecimal(orderCount).divide(new BigDecimal(pv), 4, BigDecimal.ROUND_DOWN));
        }
        return new ResultData<>(vo);
    }

    @Override
    public ResultData<BasePageResp<SpuSellDataVO>> getSpuSellDataPage(SpuSellDataReq req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        req.setTenantId(user.getShopId());
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<SpuSellDataVO> list = orderSkuMapper.findSpuSellData(req);
        if (!CollectionUtils.isEmpty(list)) {
            Map<Long, Spu> spuMap = daoService.getSpuMap(list.stream().map(SpuSellDataVO::getSpuId).collect(Collectors.toList()));
            list.stream().forEach(item -> {
                item.setSpuImage(spuMap.get(item.getSpuId()).getMainImage());
            });
        }
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public BaseResp editOrderRemark(Orders orders) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        orders.setTenantId(user.getShopId());
        ordersMapper.updateFlagAndRemarkById(orders);

        if (orders.getRemark() != null) {
            //快递助手修改备注
            updateRemark(orders.getId());
        }
        return new BaseResp();
    }

    private void updateRemark(Long orderId) {
        Orders orders = ordersMapper.selectByPrimaryKey(orderId);
        Shop shop = shopMapper.selectByPrimaryKey(orders.getTenantId());
        if (shop.getMallUserId() > 0) {
            KdzsPrintTradeUpdateRequest updateRequest = new KdzsPrintTradeUpdateRequest();
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            updateRequest.setModified(format.format(new Date()));
            updateRequest.setTid(orders.getId().toString());
            updateRequest.setMallUserId(shop.getMallUserId());
            updateRequest.setSellerMemo(orders.getRemark());
            kuaidizsService.updateTrade(updateRequest);
        }
    }

    @Override
    public BaseResp editShopIntroduction(CompanyIntroduction req) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Tenant tenant = new Tenant();
        if (req.getContent() != null || req.getVideoUrl() != null) {
            tenant.setId(user.getShopId());
            tenant.setContent(req.getContent());
            tenant.setVideoUrl(req.getVideoUrl());
            tenantMapper.updateContentAndVideoUrlAndUpdatedAtById(tenant);
        }
        if (req.getImageList() != null) {
            shopMapper.updateImageListById(req.getImageList(), user.getShopId());
        }
        return new BaseResp();
    }

    @Override
    public BaseResp editAutoReplyFormat(String replyFormat) {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        tenantMapper.updateAutoReplyFormatById(replyFormat, user.getShopId());
        return new BaseResp();
    }
}